using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using CodePlex.DnD4eCampaignManager.Presentation;
using CodePlex.DnD4eCampaignManager.Presentation.ViewInterfaces;
using CodePlex.DnD4eCampaignManager.Repositories.Interfaces;
using CodePlex.DnD4eCampaignManager.Services.Interfaces;
using NUnit.Framework;
using Rhino.Mocks;

namespace CodePlex.DnD4eCampaignManager.PresentationTests
{
    [TestFixture]
    public class CharacterManagerPresenterTests : BasePresenterTests
    {
        [Test]
        public void CloseSelectedTabDoesNothingWhenATabIsNotSelected()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.SelectedTabName).Return(string.Empty);
                Expect.Call(view.TabCount).Return(1);
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.CloseSelectedTab();
            }
        }

        [Test]
        public void CloseSelectedTabRemovesATabWhenATabIsSelected()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.SelectedTabName).Return("Name");
                view.RemoveTab("Name");
                Expect.Call(view.TabCount).Return(0);
                view.CloseButtonVisible = false;
            }
            using ( Mocks.Playback() )
            {
                presenter.CloseSelectedTab();
            }
        }

        [Test]
        public void DisplayCombatTrackerLoadsATabWithTheCombatTracker()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                view.AddCombatTrackerTab();
            }
            using ( Mocks.Playback() )
            {
                presenter.DisplayCombatTracker();
            }
        }

        [Test]
        public void DisplayMonstersLoadsAllMonstersFromTheRepositoryAndPushesThemToTheView()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            ReadOnlyCollection<string> monsters = new ReadOnlyCollection<string>(new List<string>
                                                                                     {
                                                                                         "B",
                                                                                         "A",
                                                                                         "C"
                                                                                     });
            using ( Mocks.Record() )
            {
                Expect.Call(monsterRepository.GetAllNames()).Return(monsters);
                view.MonsterNames = ( from monster in monsters orderby monster select monster ).ToArray();
            }
            using ( Mocks.Playback() )
            {
                presenter.DisplayMonsters();
            }
        }

        [Test]
        public void DisplayPlayerCharactersLoadsAllPlayerCharactersFromTheRepositoryAndPushesThemToTheView()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            ReadOnlyCollection<string> playerCharacters = new List<string>
                                                              {
                                                                  "B",
                                                                  "A",
                                                                  "C"
                                                              }.AsReadOnly();
            using ( Mocks.Record() )
            {
                Expect.Call(playerCharacterRepository.GetAllNames()).Return(playerCharacters);
                view.PlayerCharacterNames = ( from playerCharacter in playerCharacters orderby playerCharacter select playerCharacter ).ToArray();
            }
            using ( Mocks.Playback() )
            {
                presenter.DisplayPlayerCharacters();
            }
        }

        [Test]
        public void WhenAMonsterMenuItemIsClickedTheMonsterEditorTabIsLoadedWithThatMonster()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.ClickedMenuItemTag).Return("Monster_YourMom");
                Expect.Call(view.ClickedMenuItemText).Return("Your Mom");
                Expect.Call(view.TabCount).Return(1);
                view.AddMonsterEditorTab("Your Mom");
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.ProcessMenuItemClick();
            }
        }

        [Test]
        public void WhenAPlayerCharacterMenuItemIsClickedThePlayerCharacterEditorTabIsLoadedWithThatPlayerCharacter()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.ClickedMenuItemTag).Return("PlayerCharacter_YourMom");
                Expect.Call(view.ClickedMenuItemText).Return("Your Mom");
                Expect.Call(view.TabCount).Return(1);
                view.AddPlayerCharacterEditorTab("Your Mom");
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.ProcessMenuItemClick();
            }
        }

        [Test]
        public void WhenTheCombatTrackerMenuItemIsClickedTheCombatTrackerTabIsLoaded()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.ClickedMenuItemTag).Return("CombatTracker");
                Expect.Call(view.TabCount).Return(1);
                view.AddCombatTrackerTab();
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.ProcessMenuItemClick();
            }
        }

        [Test]
        public void WhenTheNewLocationMenuItemIsClickAnEmptyLocationEditorTabIsOpened()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.ClickedMenuItemTag).Return("NewLocation");
                Expect.Call(view.TabCount).Return(1);
                view.AddLocationEditorTab(string.Empty);
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.ProcessMenuItemClick();
            }
        }

        [Test]
        public void WhenTheNewMonsterMenuItemIsClickedTheMonsterEditorTabIsLoaded()
        {
            ICampaignManagerView view = Mocks.StrictMock<ICampaignManagerView>();
            IPlayerCharacterRepository playerCharacterRepository = Mocks.StrictMock<IPlayerCharacterRepository>();
            IMonsterRepository monsterRepository = Mocks.StrictMock<IMonsterRepository>();
            IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderMonsterImporter>();
            IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter =
                Mocks.StrictMock<IDungeonsAndDragonsInsiderPlayerCharacterImporter>();
            ILocationRepository locationRepository = Mocks.StrictMock<ILocationRepository>();
            CampaignManagerPresenter presenter = new CampaignManagerPresenter(view, playerCharacterRepository, monsterRepository, locationRepository,
                                                                              dungeonsAndDragonsInsiderMonsterImporter,
                                                                              dungeonsAndDragonsInsiderPlayerCharacterImporter);
            using ( Mocks.Record() )
            {
                Expect.Call(view.ClickedMenuItemTag).Return("NewMonster");
                Expect.Call(view.TabCount).Return(1);
                view.AddMonsterEditorTab(string.Empty);
                view.CloseButtonVisible = true;
            }
            using ( Mocks.Playback() )
            {
                presenter.ProcessMenuItemClick();
            }
        }
    }
}